﻿/*============================================
 * 类名 :ExpressionFactory
 * 描述 :在各种不两只情况下创建表达式的类
 *   
 * 创建时间: 2010/2/5 23:30:25
 * Blog:http:www.cnblogs.com/_xbc
 *============================================*/
using System;
using System.Collections.Generic;

using System.Text;

namespace 命题证明
{
    /// <summary>在各种不同情况下创建表达式的类</summary>
    static partial class ExpressionFactory
    {
        /// <summary>从后序表达式创建表达式 </summary>
        public static Expression CreateFromAfter( string after )
        {
            return new Expression( ExpressionFactory.ConvertToMiddle( ExpressionFactory.ConvertToTree( after ) ) );
        }
        /// <summary>将树形转化为后序字符串</summary>
        /// <returns>后序字符串</returns>      
        public static string ConvertToAfter( Node node )
        {
            string result = "";
            if ( node is ConstNode )
            {
                result += Convert( ( node as ConstNode ).Value );
                //if ( !node.IsTrue )
                //    result += "┐";
            }
            else if ( node is WordNode )
            {
                result += ( node as WordNode ).Word.ToString();
                //if ( !node.IsTrue )
                //    result += "┐";
            }
            else if ( node is OperatorNode )
            {
                if ( node.Left != null )
                {
                    result += ConvertToAfter( node.Left );
                }
                result += ConvertToAfter( node.Right );
                result += ( (char)( node as OperatorNode ).Operator ).ToString();
                //if ( !node.IsTrue )
                //    result += "┐";
            }

            return result;
        }

        /// <summary>从中序表达式求后序表达式</summary> 
        public static string MiddleToAfter( string middle )
        {
            string after = "";
            //存储括号和操作符 (  ∨ ∧ ┐ 之类
            Stack<Char> op = new Stack<char>();
            for ( int i = 0; i < middle.Length; i++ )
            {
                char index = middle[i];
                if ( MainChar.IsWord( index ) )
                {
                    after += index;
                }
                else if ( index == '(' )
                {
                    op.Push( index );
                }
                else if ( index == ')' )
                {
                    while ( true )
                    {
                        char t = op.Pop();
                        if ( t == '(' )
                            break;
                        after += t;
                    }
                }
                //操作符
                else
                {
                    if ( op.Count != 0 )
                    {
                        if ( op.Peek() == MainChar.Not )
                        {
                            after += op.Pop();
                        }
                        if ( op.Count != 0 )
                        {
                            if ( ComparePriority( op.Peek(), index ) >= 0 )
                            {
                                after += op.Pop();
                                op.Push( index );
                            }
                            else
                            {
                                op.Push( index );
                            }
                        }
                        else
                        {
                            op.Push( index );
                        } //
                    }
                    else
                    {
                        op.Push( index );
                    }
                }

            }
            while ( op.Count != 0 )
            {
                after += op.Pop();
            }
            return after;
        }

        /// <summary>返回特定操作符的优先级</summary>
        static int Priority( char a )
        {
            if ( a == MainChar.Not )
                return 4;
            if ( a == MainChar.And )
                return 3;
            if ( a == MainChar.Or )
                return 2;
            if ( a == MainChar.Prove )
                return 1;
            if ( a == MainChar.ProveTwo )
                return 0;
            if ( a == '(' )
                return -1;
            return 100;
        }

        //比较运算符的优先级
        static int ComparePriority( char a, char b )
        {
            if ( Priority( a ) > Priority( b ) )
                return 1;
            if ( Priority( a ) < Priority( b ) )
                return -1;
            return 0;
        }

        /// <summary>将逻辑值转化为0 ，1值</summary> 
        public static string Convert( bool value )
        {
            if ( value )
            {
                return "1";
            }
            return "0";
        }

        /// <summary>将字符0，1转化为逻辑值，非0即真</summary> 
        public static bool Convert( char value )
        {
            if ( value == '0' )
                return false;
            return true;
        }

        /// <summary>得到一个节点的中序形式</summary>
        public static string ConvertToMiddle( Node node )
        {
            string result = "";
            if ( node is ConstNode )
            {
                //if ( !node.IsTrue )
                //    result += "┐";
                result += ExpressionFactory.Convert( ( node as ConstNode ).Value );
            }
            else if ( node is WordNode )
            {
                result += ( node as WordNode ).Word.ToString();
            }
            else if ( node is OperatorNode )
            {
                result += "(";
                result += ConvertToMiddle( node.Left );
                result += ( (char)( node as OperatorNode ).Operator ).ToString();
                result += ConvertToMiddle( node.Right );
                result += ")";
            }
            return result;
        }
        /// <summary>后序转化为中序</summary>
        public static string AfterToMiddle( string after )
        {
            return ConvertToMiddle( ConvertToTree( after ) );
        }

        /// <summary>将后序形式转化为树形</summary> 
        public static Node ConvertToTree( string afterExpression )
        {
            Stack<Node> result = new Stack<Node>();
            for ( int i = 0; i < afterExpression.Length; i++ )
            {
                char index = afterExpression[i];
                //不是操作符
                if ( !MainChar.IsOperator( index ) )
                {
                    //是字母
                    if ( !MainChar.IsConst( index ) )
                    {
                        result.Push( new WordNode( index ) );
                    }
                    //是常数0  1 
                    else
                    {
                        result.Push( new ConstNode( ExpressionFactory.Convert( index ) ) );
                    }
                }
                //是操作符
                else if ( MainChar.IsOperator( index ) )
                {

                    Node right = result.Pop();

                    Node left = null;
                    //非操作符的左节点为空
                    if ( index != MainChar.Not )
                    {
                        left = result.Pop();
                    }
                    OperatorNode t = new OperatorNode( left, right, (Operator)index );
                    if ( left != null )
                    {
                        left.Parent = t;
                    }
                    right.Parent = t;
                    result.Push( t );
                }
            }
            return result.Pop();
        }

        /// <summary></summary>
        public static Expression ConvertToExpression( List<ProveNode> proves )
        {
            string mid = "";

            for ( int i = 0; i < proves.Count; i++ )
            {
                mid += "(" + proves[i].Result.ToString() + ")" + MainChar.And.ToString();
            }
            mid = mid.Remove( mid.Length - 1 );
            return new Expression( mid );
        }

    }
}
